#pragma once

class CWeaponDlg;
class CWeapTTX;
class CAttachDlg;
class CItemsDlg;
class CDealerDlg;
struct ClassPointers
{	
	CWeaponDlg *pWeaponDlg;
	CWeapTTX   *pWeapTTX;
	CAttachDlg *pAttachDlg;
	CItemsDlg  *pItemsDlg;
	CDealerDlg *pDealerDlg;
};

//*************************************************************************
//******************************---- WEAPONS ----**************************
//*************************************************************************
#define MAX_WEAPON_TYPE_NAME			64

#define MAX_WEAPON_CLASSES			32
#define MAX_WEAPON_CLASS_ALIAS	32
#define WEAPON_CLASS_TAG			_T("WEAPONCLASS")
#define MAX_WEAPON_SOUND_PATH		64

#define MAX_WEAPON_TYPES			256
#define WEAPON_TYPE_TAG				_T("WEAPON")

#define MAX_CALIBERS					256
#define MAX_CALIBER_NAME			32
#define CALIBER_TAG					_T("CALIBER")

#define MAX_AMMOTYPES				256
#define MAX_AMMOTYPE_NAME			32
#define AMMOTYPE_TAG					_T("AMMOTYPE")

#define MAX_MAGAZINES				256
#define MAGAZINE_TAG					_T("MAGAZINE")

#define MAX_ARMOUR_CLASSES			32
#define MAX_ARMOUR_CLASS_ALIAS	32
#define ARMOUR_CLASS_TAG			_T("ARMOURCLASS")

#define MAX_ARMOUR_TYPES			256
#define ARMOUR_TYPE_TAG				_T("ARMOURTYPE")

#define MAX_EXPLOSIVE_CLASSES			32
#define MAX_EXPLOSIVE_CLASS_ALIAS	32
#define EXPLOSIVE_CLASS_TAG			_T("EXPLOSIVECLASS")

#define MAX_EXPLOSIVE_TYPES			256
#define EXPLOSIVE_TYPE_TAG				_T("EXPLOSIVETYPE")
typedef struct
{
	UINT8 ubBullets;
	UINT8 ubPenalty;
	UINT16 usROF;
} FIREMODE;
typedef struct tag_WEAPONTYPE
{
	UINT8	ubWeaponClass;             // handgun/shotgun/rifle/knife
	UINT8	ubCalibre;	               // type of ammunition needed
	UINT8	ubReadyTime;               // APs to ready/unready weapon
	UINT8	ubShotsPer4Turns;          // maximum (mechanical) firing rate
	UINT8	ubBulletSpeed;             // bullet's travelling speed
	UINT8	ubImpact;		               // weapon's max damage impact (size & speed)
	UINT8	ubDeadliness;							 // comparative ratings of guns
	UINT8	ubMagSize;
	UINT16	usRange;
	UINT16	usReloadDelay;
	TCHAR	tsWeaponType[MAX_WEAPON_TYPE_NAME]; // item box description string
	TCHAR	tsSound[MAX_WEAPON_SOUND_PATH];		// single shot sound
	TCHAR	tsBurstSound[MAX_WEAPON_SOUND_PATH];
	TCHAR	tsReloadSound[MAX_WEAPON_SOUND_PATH];
	TCHAR	tsLocknLoadSound[MAX_WEAPON_SOUND_PATH];
	UINT8	ubAttackVolume;
	UINT8	ubHitVolume;
	UINT8	ubReloadAPs;
	UINT8	ubSelfloading;
	UINT8	ubFeedType;
	UINT8	ubFixedMag;
	UINT8	ubReserved1;
	UINT8	ubReserved2;
	FIREMODE mode[3];
	UINT32	uiShotSpread;
} WEAPONTYPE;

typedef struct
{
	TCHAR alias[MAX_CALIBER_NAME];
	TCHAR sound[MAX_WEAPON_SOUND_PATH];
	TCHAR burstsound[MAX_WEAPON_SOUND_PATH];
	INT32	iPower;
} CaliberStruct;

typedef struct
{
	UINT8	ubCalibre;
	UINT8 ubMagSize;
	UINT8	ubAmmoType;
	UINT8	ubFeedType;
	UINT8 ubClip;
} MAGTYPE;

typedef struct
{
	UINT8	ubArmourClass;
	UINT8	ubProtection;
	UINT8	ubDegradePercent;
} ARMOURTYPE;

typedef struct
{
	UINT8		ubType;					// type of explosive
	UINT8		ubDamage;				// damage value
	UINT8		ubStunDamage;		// stun amount / 100
	UINT8		ubRadius;				// radius of effect
	UINT8		ubVolume;				// sound radius of explosion
	UINT8		ubVolatility;		// maximum chance of accidental explosion
	UINT8		ubAnimationID;	// Animation enum to use
} EXPLOSIVETYPE;

typedef struct
{
	TCHAR alias[MAX_AMMOTYPE_NAME];
	UINT32 armormultiplier;
	UINT32 armordivider;
	UINT32 damagemultiplier;
	UINT32 damagedivider;
	UINT32 structuremultiplier;
	UINT32 structuredivider;
} AMMOTYPE;

typedef struct
{
	TCHAR alias[MAX_WEAPON_CLASS_ALIAS];
	TCHAR reloadsound[MAX_WEAPON_SOUND_PATH];
	TCHAR lnlsound[MAX_WEAPON_SOUND_PATH];
}WEAPONCLASS;

// CWeaponDlg dialog
typedef wchar_t *				STR16;
#define NUM_OF_CALS	    256
#define NUM_OF_PAIRS		255
typedef struct CaliberBinds{
  typedef struct FeedType_MagSize_pair
  {
    UINT8 m_ui8FeedType;
    UINT8 m_ui8MagSize;
  } FT_MS_pair;

  BOOL AddPair( UINT8 ui8FeedType, UINT8 ui8MagSize )
  {
    if ( ui8FeedType == 255 )
      return TRUE;

    if ( LastFree >= NUM_OF_PAIRS )
      return FALSE;

    bool should_insert = true;

    for ( int i = 0; i < LastFree; i++ )
      if ( pairs[ i ].m_ui8FeedType == ui8FeedType && pairs[ i ].m_ui8MagSize == ui8MagSize )
      {
        should_insert = false;
        break;
      }

    if ( !should_insert )
      return TRUE;

    pairs[ LastFree ].m_ui8FeedType = ui8FeedType;
    pairs[ LastFree ].m_ui8MagSize  = ui8MagSize;
    LastFree++;
    return TRUE;
  }
  FT_MS_pair pairs[NUM_OF_PAIRS];
	UINT8 LastFree;
}CaliberBinds;

struct WSPointers{
	WEAPONTYPE *Weapon;
	ARMOURTYPE *Armour;
	MAGTYPE *Magazine;
	EXPLOSIVETYPE *Explosive;
	CaliberStruct *gCalibers;	
	AMMOTYPE *gAmmoTypes;
	WEAPONCLASS *gWeaponClass;
	CaliberBinds *ftbBinds;
};